package dashboard.classinfo;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;

public class TypeTest {

	/*
	 * Interger.TYPE == int.class 是基本类型int的Class的引用，int是基本类型在虚拟机运行时就已经加载了他的Class.
	 *Interger.class 是int的封装类Interger的引用。 因此二者是不同的。
	 */
	 int intField=1;
	 Integer integerField = 2;

    
    public static ObjectDeserializer getDeserializer(Type type) {

        if (type instanceof Class<?>) {
           System.err.println("type instanceof Class<?>: " + type);
        }

        if (type instanceof ParameterizedType) {
        	System.err.println("type instanceof ParameterizedType: " + type);
            Type rawType = ((ParameterizedType) type).getRawType();
            Type actualTypeType = ((ParameterizedType) type).getActualTypeArguments()[0];
            if (rawType instanceof Class<?>) {
            	 System.err.println("rawType instanceof Class<?>: " + rawType);
            	 System.err.println("actualTypeType: " + actualTypeType);
            } else {
                return getDeserializer(rawType);
            }
        }

        return JavaObjectDeserializer.instance;
    }
    
	/**
	 * @param args
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 */
	public static void main(String[] args) throws SecurityException, NoSuchFieldException {
		TypeReference<List<String>> typeReference = new TypeReference<List<String>>(){};
		System.err.println(typeReference.getClass());
		System.err.println(typeReference.getType());
		getDeserializer(typeReference.getType());
		
		List<String> strings = new ArrayList<String>();;
		System.err.println(strings.getClass().getComponentType());
		
        List<String> ls = new ArrayList<String>();
        List<String> ls0 = new ArrayList<String>(){};
        List<Integer> li = new ArrayList<Integer>();
        System.out.println(ls.getClass() == li.getClass());
        System.out.println(ls.getClass() == ls0.getClass());
        
        Type ls0Type = ls0.getClass().getGenericSuperclass();
        System.out.println(ls0Type);
        System.out.println(((ParameterizedType) ls0Type).getActualTypeArguments()[0]);
        
        
//		List<String> list = new ArrayList<String>();
//		List l = list;
//		l.add(123);
//		System.out.println(l.get(0));
        
		//正规用法
		List<String> list1 = ArrayUtils.asList("A","B");
		//参数为空
		List list2 = ArrayUtils.asList();
		//参数为数字和字符串的混合   不指定泛型的时候*/  
		List<? extends Number> list3 = ArrayUtils.asList(1,2,3.1);
		
//		unmodifiableList(list2);
		
	       /**不指定泛型的时候*/  
        int i=add(1, 2); //这两个参数都是Integer，所以T为Integer类型  
        Number f=add(1, 1.2);//这两个参数一个是Integer，以风格是Float，所以取同一父类的最小级，为Number  
        /* 当返回的不是T 而是 List<T> 时需要用 List<? extends Number> */
        Object o=add(1, "asd");//这两个参数一个是Integer，以风格是Float，所以取同一父类的最小级，为Object  
        
        /**指定泛型的时候*/  
        int a=TypeTest.<Integer>add(1, 2);//指定了Integer，所以只能为Integer类型或者其子类  
//        int b=TypeTest.<Integer>add(1, 2.2);//编译错误，指定了Integer，不能为Float  
        Number c=TypeTest.<Number>add(1, 2.2); //指定为Number，所以可以为Integer和Float 
        
        System.err.println("integerField: " + TypeTest.class.getDeclaredField("integerField").getType());
        System.err.println("intField: " + TypeTest.class.getDeclaredField("intField").getType());
	}

	 //这是一个简单的泛型方法  
    public static <T> T add(T x,T y){  
        return y;  
    } 
    
    
    /**
	 * 返回一个不可修改的List
	 * 
	 * @return
	 */
//	public static <T> List<T> unmodifiableList(List<? extends T> list) {
//		return Collections.unmodifiableList(list);
//	}
//	
	/**
	 * 返回一个不可修改的List
	 * 
	 * @return
	 */
	public static List<Number> unmodifiableList(List<? extends Number> list) {
//		list.add(new Integer(1));
		return Collections.unmodifiableList(list);
	}
	/**
	 * 返回map的所有key
	 * 
	 * @return
	 */
	public static <K, V> List<K> test(Map<K, V> map) {
		List<K> list = new ArrayList<K>();
		Iterator<K> it = map.keySet().iterator();
		while (it.hasNext()) {
			K k = it.next();
			list.add(k);
		}
		return list;
	}
	
}

class ArrayUtils{
	//把一个变长参数转变为列表
	public  static <T> List<T> asList(T...t){
		List<T> list = new ArrayList<T>();
		Collections.addAll(list, t);
		return list;
	}
}
